from flask import Blueprint, jsonify, current_app, request
from sqlalchemy import asc

from models import Course, Teacher, db  # 假设 Course, Teacher 是模型，db 是数据库实例
from sqlalchemy.exc import IntegrityError

api_bp = Blueprint('course', __name__)


# 1. 获取课程列表
@api_bp.route('/courses', methods=['GET'])
def get_courses():
    try:
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('page_size', 10, type=int)
        page_size = min(max(page_size, 1), 100)

        # 关键词查询参数
        keyword = request.args.get('kw', '').strip()

        # 构建基础查询
        query = Course.query.join(
            Teacher, Course.teacher_id == Teacher.id, isouter=True
        ).add_columns(
            Course.id,
            Course.name,
            Course.courseId,
            Course.credits,
            Course.hours,
            Course.type,
            Course.description,
            Teacher.id.label('teacher_id'),
            Teacher.name.label('teacher_name'),
        ).order_by(asc(Course.id))

        # 添加关键词查询条件
        if keyword:
            keyword = f'%{keyword}%'  # 模糊查询
            query = query.filter(
                (Course.name.ilike(keyword)) |
                (Course.courseId.ilike(keyword)) |
                (Teacher.name.ilike(keyword))  # 支持班级名称搜索
            )

        # 查询总记录数（带关键词条件）
        total_items = query.count()

        # 计算总页数
        total_pages = (total_items + page_size - 1) // page_size
        page = max(1, min(page, total_pages))  # 防止页码越界

        # 执行分页查询
        courses = query.offset((page - 1) * page_size).limit(page_size).all()

        data = []
        for course in courses:
            data.append({
                "id": course.id,
                "name": course.name,
                "course_id": course.courseId,
                "credits": course.credits,
                "hours": course.hours,
                "teacher_id": course.teacher_id,
                "teacher_name": course.teacher_name,
                "type": course.type,
                "description": course.description
            })

        return jsonify({
            "message": "获取课程列表成功",
            "data": data,
            "pagination": {
                "current_page": page,
                "page_size": page_size,
                "total_pages": total_pages,
                "total_items": total_items
            }
        }), 200

    except Exception as e:
        current_app.logger.error(f"获取课程列表失败: {str(e)}", exc_info=True)
        return jsonify({"message": "获取课程列表失败"}), 500


# 2. 添加课程
@api_bp.route('/courses', methods=['POST'])
def add_course():
    try:
        data = request.json
        required_fields = ["name", "course_id", "credits", "hours", "teacher_id", "type"]
        for field in required_fields:
            if field not in data:
                return jsonify({"message": f"缺少必要参数: {field}"}), 400

        # 检查课程ID是否已存在
        existing_course = Course.query.filter_by(courseId=data["course_id"]).first()
        if existing_course:
            return jsonify({"message": f"课程ID {data['course_id']} 已存在"}), 400

        # 验证教师是否存在
        teacher = Teacher.query.get(data["teacher_id"])
        if not teacher:
            return jsonify({"message": "教师不存在"}), 400

        # 验证课程类型
        valid_types = ["基础课", "必修课", "选修课", "实践课"]
        if data["type"] not in valid_types:
            return jsonify({"message": f"无效的课程类型，必须是 {', '.join(valid_types)} 之一"}), 400

        new_course = Course(
            name=data["name"],
            courseId=data["course_id"],
            credits=data["credits"],
            hours=data["hours"],
            teacher_id=data["teacher_id"],
            type=data["type"],
            description=data.get("description", "")
        )
        db.session.add(new_course)
        db.session.commit()
        return jsonify({
            "message": "课程添加成功",
            "course_id": new_course.id
        }), 201

    except IntegrityError:
        db.session.rollback()
        current_app.logger.error("数据库操作冲突")
        return jsonify({"message": "添加课程失败"}), 500
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"添加课程失败: {str(e)}", exc_info=True)
        return jsonify({"message": "添加课程失败"}), 500


# 3. 更新课程信息
@api_bp.route('/courses/<int:course_id>', methods=['PUT'])
def update_course(course_id):
    try:
        data = request.json
        course = Course.query.get(course_id)

        if not course:
            return jsonify({"message": "课程记录不存在"}), 404

        # 检查课程ID是否被修改且新ID已存在
        if "course_id" in data and data["course_id"] != Course.courseId:
            existing_course = Course.query.filter(
                Course.courseId == data["course_id"],
                Course.id != course_id
            ).first()
            if existing_course:
                return jsonify({"message": f"课程ID {data['course_id']} 已被其他课程使用"}), 400

        # 验证教师是否存在（如果更新了教师）
        if "teacher_id" in data:
            teacher = Teacher.query.get(data["teacher_id"])
            if not teacher:
                return jsonify({"message": "教师不存在"}), 400

        # 验证课程类型
        if "type" in data:
            valid_types = ["基础课","必修课", "选修课", "实践课"]
            if data["type"] not in valid_types:
                return jsonify({"message": f"无效的课程类型，必须是 {', '.join(valid_types)} 之一"}), 400

        # 更新课程信息
        if "name" in data:
            course.name = data["name"]
        if "course_id" in data:
            course.courseId = data["course_id"]
        if "credits" in data:
            course.credits = data["credits"]
        if "hours" in data:
            course.hours = data["hours"]
        if "teacher_id" in data:
            course.teacher_id = data["teacher_id"]
        if "type" in data:
            course.type = data["type"]
        if "description" in data:
            course.description = data["description"]

        db.session.commit()

        return jsonify({
            "message": "课程信息更新成功",
            "course_id": course.id
        }), 200

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新课程信息失败: {str(e)}", exc_info=True)
        return jsonify({"message": "更新课程信息失败"}), 500


# 4. 删除课程
@api_bp.route('/courses/<int:course_id>', methods=['DELETE'])
def delete_course(course_id):
    try:
        course = Course.query.get(course_id)

        if not course:
            return jsonify({"message": "课程记录不存在"}), 404

        # 检查是否有关联成绩
        if course.scores:
            return jsonify({"message": "该课程有关联成绩，无法删除"}), 400

        db.session.delete(course)
        db.session.commit()

        return jsonify({"message": "课程已删除"}), 200

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除课程失败: {str(e)}", exc_info=True)
        return jsonify({"message": "删除课程失败"}), 500
